package com.ocn.li.scmdy.common.qcloud;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.InputStream;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author gyz
 * @version 创建时间：2018年7月6日 上午9:16:58
 * 类说明
 */
@Slf4j
public class UploadVideo {
    public static String SecretId = GameUtils.SecretId;
    // 云API密钥StrSecKey
    public static String StrSecKey = GameUtils.StrSecKey;
    // bucket名称
    public static String bucket = GameUtils.bucket;
    // 直播点播appId
    public static String appId = GameUtils.appId;
    // 地域信息
    public static String region = GameUtils.region;

	/**
	 * 文件上传
	 *
	 * @param file
	 */
	public static String upload(File file, String fileName, String cosKey) {
		return upload(file, fileName, cosKey, true);
	}
	
	public static String upload(File file, String fileName, String cosKey,boolean isRename) {
		if (StrUtil.isEmpty(fileName)) {
			StaticLog.error("上传文件名为空");
			return null;
		}
		if (ObjectUtil.isNull(file)) {
			StaticLog.error("上传文件为空");
			return null;
		}
		if (!FileUtil.exist(file)) {
			StaticLog.error("上传文件不存在");
			return null;
		}
		if (!FileUtil.isFile(file)) {
			StaticLog.error("不可上传非单文件");
			return null;
		}
		COSClient cosclient = null;
		TransferManager transferManager = null;
		try {
			// 1 初始化用户身份信息(secretId, secretKey)
			COSCredentials cred = new BasicCOSCredentials(SecretId, StrSecKey);
			// 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
			ClientConfig clientConfig = new ClientConfig(new Region(region));
			//System.out.println("region:"+region);
			// 3 生成cos客户端
			cosclient = new COSClient(cred, clientConfig);
			// bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式

			// 指定要上传到 COS 上对象键
			// 对象键（Key）是对象在存储桶中的唯一标识。例如，在对象的访问域名 `bucket1-1250000000.cos.ap-guangzhou.myqcloud.com/doc1/pic1.jpg` 中，对象键为 doc1/pic1.jpg, 详情参考 [对象键](https://cloud.tencent.com/document/product/436/13324)
			//如果有文件夹的需要在key里面配置，如mytest这个文件夹
			//key是上传的文件的名字
			StringBuffer keySb = new StringBuffer();
			if (StrUtil.isNotEmpty(cosKey)) {
				keySb.append(cosKey).append("/");
			}
			if (isRename || StrUtil.isEmpty(fileName)) {
				keySb.append(UUID.randomUUID().toString());
				String extName = FileUtil.extName(fileName);
				if (StrUtil.isNotEmpty(extName)) {
					keySb.append(".").append(extName);
				}
			} else {
				keySb.append(fileName);
			}
			String key = keySb.toString();
			if (file != null) {
				Long length = FileUtil.size(file);
				StaticLog.info("文件的长度是：{},存储key：{}", length, key);
				PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
				String eTag = null;
				if (length <= 20 * 1024 * 1024) {
					// 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
					PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
					eTag = putObjectResult.getETag();
				} else {
					//使用高级API上传文件
					ExecutorService threadPool = Executors.newFixedThreadPool(32);
					// 传入一个 threadpool, 若不传入线程池, 默认 TransferManager 中会生成一个单线程的线程池。
					transferManager = new TransferManager(cosclient, threadPool);
					// 本地文件上传
					Upload upload = transferManager.upload(putObjectRequest);
					// 等待传输结束（如果想同步的等待上传结束，则调用 waitForCompletion）
					UploadResult uploadResult = upload.waitForUploadResult();
					eTag = uploadResult.getETag();
				}
				StaticLog.info("eTag:{}", eTag);
				//这个访问路径可以拼接的http://+桶名+"."+域+".myqcloud.com"+"/"+键
				//String urls = "http://" + bucket + ".coscd.myqcloud.com/" + key;
				return StrUtil.format("https://{}.coscd.myqcloud.com/{}", bucket, key);//使用https，小程序
			} else {
				return null;
			}
		} catch (Exception e) {
			StaticLog.error(e, "上传腾讯云失败");
		} finally {
			//关闭客户端连接
			if (ObjectUtil.isNotNull(cosclient)) {
				cosclient.shutdown();
			}
			// 关闭 TransferManger
			if (ObjectUtil.isNotNull(transferManager)) {
				transferManager.shutdownNow();
			}
			if (ObjectUtil.isNotNull(file)) {
				FileUtil.del(file);
			}
		}
		return null;
	}

	/**
	 * 上传头像文件
	 *
	 * @param localFile
	 */
	public static String uploadHeadImg(MultipartFile localFile, String cosKey) {
		return uploadImg(localFile, cosKey, 300, 400);
	}

	/**
	 * 上传图片文件
	 *
	 * @param localFile
	 */
	public static String uploadImg(MultipartFile localFile, String cosKey, Integer width, Integer height) {
		try {
			//将MulitiFile转换成File
			File tempFile = convertFile(localFile);
			Thumbnails.of(tempFile).size(width, height).toFile(tempFile);
			return upload(tempFile, localFile.getOriginalFilename(), cosKey);
		} catch (Exception e) {
			StaticLog.error(e);
		}
		return null;
	}

	public static String uploadGoodImg(MultipartFile localFile, String cosKey) {
		try {
			//将MulitiFile转换成File
			File tempFile = convertFile(localFile);
			String type = FileUtil.extName(tempFile);
			if (!StrUtil.equals(type, "gif")) {//非gif图片转化
				Thumbnails.of(tempFile).scale(1f).outputQuality(0.5f).toFile(tempFile);
			}
			return upload(tempFile, localFile.getOriginalFilename(), cosKey);
		} catch (Exception e) {
			StaticLog.error(e);
		}
		return null;
	}

	/**
	 * 上传小程序二维码图片文件
	 *
	 * @param
	 */
	public static String uploadBase64WxaCodeImg(String base64, String name, String cosKey) {
		try {
			//将MulitiFile转换成File
			File tempFile = convertBase64File(base64, name);
			String type = FileUtil.extName(tempFile);
			if (!StrUtil.equals(type, "gif")) {//非gif图片转化
				Thumbnails.of(tempFile).scale(1f).outputQuality(0.5f).toFile(tempFile);
			}
			return upload(tempFile, name, cosKey, false);
		} catch (Exception e) {
			StaticLog.error(e);
		}
		return null;
	}

	/**
	 * WEB上传文件
	 *
	 * @param localFile
	 */
	public static String uploadWebFile(MultipartFile localFile, String cosKey) {
		try {
			//将MulitiFile转换成File
			File tempFile = convertFile(localFile);
			return upload(tempFile, localFile.getOriginalFilename(), cosKey);
		} catch (Exception e) {
			StaticLog.error(e);
		}
		return null;
	}

    public static String uploadSmallBySize(MultipartFile localFile, String cosKey,Integer width,Integer height) {

        //		log.info("------------------------"+SecretId+"="+StrSecKey+"="+bucket+"="+appId+"="+region);

        try {
            // 1 初始化用户身份信息(secretId, secretKey)
            COSCredentials cred = new BasicCOSCredentials(SecretId, StrSecKey);
            // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(region));
//			System.out.println("region:"+region);
            // 3 生成cos客户端
            COSClient cosclient = new COSClient(cred, clientConfig);
            // bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式
            //将MulitiFile转换成File
            File tempFile=convertFile(localFile);
			System.out.println(localFile.getOriginalFilename());
			System.out.println(localFile.getOriginalFilename());
            Thumbnails.of(localFile.getOriginalFilename()).size(width, height).toFile(localFile.getOriginalFilename());
            File file = new File(localFile.getOriginalFilename());


            if (file != null) {
                // 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
                // 大文件上传请参照 API 文档高级 API 上传
                //File localFile = new File("D://workspace/video/src/test/resources/timg.jpg");
                System.out.println("文件的长度是：" + file.length());
                // 指定要上传到 COS 上对象键
                // 对象键（Key）是对象在存储桶中的唯一标识。例如，在对象的访问域名 `bucket1-1250000000.cos.ap-guangzhou.myqcloud.com/doc1/pic1.jpg` 中，对象键为 doc1/pic1.jpg, 详情参考 [对象键](https://cloud.tencent.com/document/product/436/13324)
                //如果有文件夹的需要在key里面配置，如mytest这个文件夹
                //key是上传的文件的名字
                String key = cosKey + "/" + UUID.randomUUID().toString() + localFile.getOriginalFilename().substring(
                        localFile.getOriginalFilename().lastIndexOf("."));
//				System.out.println("bucket："+bucket);
//				System.out.println("key:"+key);


                PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
                PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
                //这个访问路径可以拼接的http://+桶名+"."+域+".myqcloud.com"+"/"+键
                String urls = "https://" + bucket + ".coscd.myqcloud.com/" + key;//使用https，小程序


                //String url="http://video-test-1253520711.coscd.myqcloud.com/mytest/upload.jpg";
                cosclient.shutdown();
                return urls;//http://hyshop-1253520711.coscd.myqcloud.com/good/8b059290-f03e-4b8d-95d2-1bb9f4dc5968.png
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 大的文件上传（4GB到5TB）
     *
     * @param localFile
     * @return
     */
    public static String uploadLarge(MultipartFile localFile) {
        try {
            // 1 初始化用户身份信息(secretId, secretKey)
            COSCredentials cred = new BasicCOSCredentials(SecretId, StrSecKey);
            // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(region));
            // 3 生成cos客户端
            COSClient cosclient = new COSClient(cred, clientConfig);
            // bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式
            //将MulitiFile转换成File
            File file = convertFile(localFile);
            if (file != null) {
                //使用高级API上传文件
                ExecutorService threadPool = Executors.newFixedThreadPool(32);
                // 传入一个 threadpool, 若不传入线程池, 默认 TransferManager 中会生成一个单线程的线程池。
                TransferManager transferManager = new TransferManager(cosclient, threadPool);
                // .....(提交上传下载请求, 如下文所属)

                // 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
                // 大文件上传请参照 API 文档高级 API 上传


                // 指定要上传到 COS 上对象键
                // 对象键（Key）是对象在存储桶中的唯一标识。例如，在对象的访问域名 `bucket1-1250000000.cos.ap-guangzhou.myqcloud.com/doc1/pic1.jpg` 中，对象键为 doc1/pic1.jpg, 详情参考 [对象键](https://cloud.tencent.com/document/product/436/13324)
                String key = UUID.randomUUID().toString() + localFile.getOriginalFilename().substring(
                        localFile.getOriginalFilename().lastIndexOf("."));
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
                // 本地文件上传
                Upload upload = transferManager.upload(putObjectRequest);
                // 等待传输结束（如果想同步的等待上传结束，则调用 waitForCompletion）
                UploadResult uploadResult = upload.waitForUploadResult();
                //关闭客户端连接
                cosclient.shutdown();
                // 关闭 TransferManger
                transferManager.shutdownNow();
                //这个访问路径可以拼接的http://+桶名+"."+域+".myqcloud.com"+"/"+键
                String urls = "https://" + bucket + ".coscd.myqcloud.com/" + key;//使用https，小程序
                return urls;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 删除某个cos视频文件
     */
    public static void deleteCos(String key) {
        try {
            // 1 初始化用户身份信息(secretId, secretKey)
            COSCredentials cred = new BasicCOSCredentials(SecretId, StrSecKey);
            // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(region));
            // 3 生成cos客户端
            COSClient cosclient = new COSClient(cred, clientConfig);

            cosclient.deleteObject(bucket, key);
            //关闭客户端连接
            cosclient.shutdown();
        } catch (Exception e) {

        }
    }

	/**
	 * 将MultiFile转换成File
	 *
	 * @return
	 */
	public static File convertFile(MultipartFile localFile) {
		InputStream ins = null;
		try {
			File file = createTempFile("temp", localFile.getOriginalFilename());//临时文件
			ins = localFile.getInputStream();
			FileUtil.writeFromStream(ins, file);
			return file;
		} catch (Exception e) {
			StaticLog.error(e);
		} finally {
			if (ObjectUtil.isNotNull(ins)) {
				IoUtil.close(ins);
			}
		}
		return null;
	}

	private static File createTempFile(String dir, String name) {
		File tempDir = new File(dir);//临时文件夹
		if (!FileUtil.exist(tempDir)) {
			FileUtil.mkdir(tempDir);
		}
		String suffix = null;
		String extName = FileUtil.extName(name);
		if (StrUtil.isNotEmpty(extName)) {
			suffix = "." + extName;
		}
		File file = FileUtil.createTempFile("temp", suffix, tempDir, true);
		return file;
	}
	
	/**
	 * 将base64转换成File
	 *
	 * @return
	 */
	public static File convertBase64File(String base64, String name) {
		try {
			File file = createTempFile("temp/wxa",name);//临时文件
			FileUtil.writeBytes(Base64.decode(base64), file);
			return file;
		} catch (Exception e) {
			StaticLog.error(e);
		} finally {
		}
		return null;
	}

    public static String uploadSmall(File localFile, String cosKey) {
        try {
            // 1 初始化用户身份信息(secretId, secretKey)
            COSCredentials cred = new BasicCOSCredentials(SecretId, StrSecKey);
            // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
            ClientConfig clientConfig = new ClientConfig(new Region(region));
            System.out.println("region:" + region);
            // 3 生成cos客户端
            COSClient cosclient = new COSClient(cred, clientConfig);
            // bucket的命名规则为{name}-{appid} ，此处填写的存储桶名称必须为此格式
            if (localFile != null) {
                // 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20M以下的文件使用该接口
                // 大文件上传请参照 API 文档高级 API 上传
                //File localFile = new File("D://workspace/video/src/test/resources/timg.jpg");
                System.out.println("文件的长度是：" + localFile.length());
                // 指定要上传到 COS 上对象键
                // 对象键（Key）是对象在存储桶中的唯一标识。例如，在对象的访问域名 `bucket1-1250000000.cos.ap-guangzhou.myqcloud.com/doc1/pic1.jpg` 中，对象键为 doc1/pic1.jpg, 详情参考 [对象键](https://cloud.tencent.com/document/product/436/13324)
                //如果有文件夹的需要在key里面配置，如mytest这个文件夹
                //key是上传的文件的名字
                String key = "/" + cosKey + "/" + UUID.randomUUID().toString() + localFile.getName().substring(
                        localFile.getName().lastIndexOf("."));
                System.out.println("bucket：" + bucket);
                System.out.println("key:" + key);
                PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, localFile);
                PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
                //这个访问路径可以拼接的http://+桶名+"."+域+".myqcloud.com"+"/"+键
                String urls = "https://" + bucket + ".coscd.myqcloud.com/" + key;//使用https，小程序
                //String url="http://video-test-1253520711.coscd.myqcloud.com/mytest/upload.jpg";
                cosclient.shutdown();
                return urls;
            } else {
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static void deleteFile(String url) {
        if (url != null && !url.equals("")) {
            String[] urls = url.split("myqcloud.com/");
            if (urls != null && urls.length != 0) {
                String key = urls[1];
                System.out.println("key:" + key);
                if (!key.equals("")) {
                    UploadVideo.deleteCos(key);
                }
            }
        }
    }

    /**
     * 获取文件扩展名
     *
     * @param filename 文件名
     * @return
     */
    public static String getExtensionName(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length() - 1))) {
                return filename.substring(dot + 1);
            }
        }
        return filename;
    }

    /**
     * 获取不带扩展名的文件名
     *
     * @param filename 文件
     * @return
     */
    private static String getFileNameWithoutEx(String filename) {
        if ((filename != null) && (filename.length() > 0)) {
            int dot = filename.lastIndexOf('.');
            if ((dot > -1) && (dot < (filename.length()))) {
                return filename.substring(0, dot);
            }
        }
        return filename;
    }

}
